package com.pangu.ui.browser;

import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.LayoutManager;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import java.util.ArrayList;
import java.util.List;

/**
 * 带有头部和尾部视图的抽象的RecyclerView适配器
 * <p/>
 * Created by cxlin
 */
public abstract class ARecyclerViewWithHeaderFooterAdapter extends Adapter {

    // 其他类型
    public static final int TYPE_MANAGER_OTHER = 0;
    // 线性类型
    public static final int TYPE_MANAGER_LINEAR = 1;
    // 规则的网格类型
    public static final int TYPE_MANAGER_GRID = 2;
    // 错开的宫格类型（类似瀑布流）
    public static final int TYPE_MANAGER_STAGGERED_GRID = 3;
    // 头部视图类型
    public static final int TYPE_HEADER_VIEW = 1001;
    // 底部视图类型
    public static final int TYPE_FOOTER_VIEW = 1002;
    // 头部视图列表
    private List<View> mHeadersView = new ArrayList<View>();
    // 底部视图列表
    private List<View> mFootersView = new ArrayList<View>();
    // manager类型
    private int mManagerType;
    private LayoutManager mManager;
    private Adapter mAdapter;

    public ARecyclerViewWithHeaderFooterAdapter(LayoutManager mLayoutManager, Adapter adapter) {
        super();
        setLayoutManager(mLayoutManager);

        this.mAdapter = adapter;
    }

    /**
     * 设置LayoutManager
     *
     * @param mLayoutManager the mLayoutManager to set
     */
    public void setLayoutManager(LayoutManager mLayoutManager) {
        setManager(mLayoutManager);
    }

    /**
     * 获取LayoutManager
     *
     * @return
     */
    public LayoutManager getLayoutManager() {
        return mManager;
    }

    /**
     * 设置LayoutManager
     *
     * @param mLayoutManager
     */
    private void setManager(RecyclerView.LayoutManager mLayoutManager) {
        this.mManager = mLayoutManager;
        if (mManager instanceof GridLayoutManager) {
            mManagerType = TYPE_MANAGER_GRID;
            ((GridLayoutManager) mManager).setSpanSizeLookup(mSpanSizeLookup);

        } else if (mManager instanceof LinearLayoutManager) {
            mManagerType = TYPE_MANAGER_LINEAR;

        } else if (mManager instanceof StaggeredGridLayoutManager) {
            mManagerType = TYPE_MANAGER_STAGGERED_GRID;
            ((StaggeredGridLayoutManager) mManager).setGapStrategy(StaggeredGridLayoutManager
                    .GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);

        } else {
            mManagerType = TYPE_MANAGER_OTHER;
        }
    }

    /**
     * 获得宫格列数
     *
     * @param position
     * @return
     */
    public int getGridSpan(int position) {
        if (isHeader(position) || isFooter(position)) {
            return getSpanCount();
        }

        return 1;
    }

    /**
     * 获取列数
     *
     * @return
     */
    private int getSpanCount() {
        if (mManager instanceof GridLayoutManager) {
            return ((GridLayoutManager) mManager).getSpanCount();
        } else if (mManager instanceof StaggeredGridLayoutManager) {
            return ((StaggeredGridLayoutManager) mManager).getSpanCount();
        }

        return 1;
    }

    private GridLayoutManager.SpanSizeLookup mSpanSizeLookup = new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            return getGridSpan(position);
        }
    };

    /**
     * 根据位置判断是否为头部视图
     *
     * @param position
     * @return
     */
    private boolean isHeader(int position) {
        return (position < mHeadersView.size());
    }

    /**
     * 根据位置判断是否为底部视图
     *
     * @param position
     * @return
     */
    private boolean isFooter(int position) {
        return (position >= mHeadersView.size() + mAdapter.getItemCount());
    }

    @Override
    public int getItemViewType(int position) {
        if (isHeader(position)) {
            return TYPE_HEADER_VIEW;

        } else if (isFooter(position)) {
            return TYPE_FOOTER_VIEW;
        }

        int type = mAdapter.getItemViewType(position - mHeadersView.size());
        if (type == TYPE_HEADER_VIEW || type == TYPE_FOOTER_VIEW) {
            throw new IllegalArgumentException("Item type cannot equal " + TYPE_HEADER_VIEW + " or " +
                    TYPE_FOOTER_VIEW);
        }

        return type;
    }

    /**
     * 添加头部视图
     *
     * @param header
     */
    public void addHeader(View header) {
        if (header != null && !mHeadersView.contains(header)) {
            mHeadersView.add(header);
            notifyItemInserted(mHeadersView.size() - 1);
        }
    }

    /**
     * 移除头部视图
     *
     * @param header
     */
    public void removeHeader(View header) {
        if (mHeadersView.contains(header)) {
            notifyItemRemoved(mHeadersView.indexOf(header));
            mHeadersView.remove(header);
        }
    }

    /**
     * 添加底部视图
     *
     * @param footer
     */
    public void addFooter(View footer) {
        if (footer != null && !mFootersView.contains(footer)) {
            mFootersView.add(footer);
            notifyItemInserted(mHeadersView.size() + mAdapter.getItemCount() + mFootersView.size() - 1);
        }
    }

    /**
     * 移除底部视图
     *
     * @param footer
     */
    public void removeFooter(View footer) {
        if (mFootersView.contains(footer)) {
            notifyItemRemoved(mHeadersView.size() + mAdapter.getItemCount() + mFootersView.indexOf(footer));
            mFootersView.remove(footer);
        }
    }

    @Override
    public int getItemCount() {
        return mHeadersView.size() + mAdapter.getItemCount() + mFootersView.size();
    }

    public int getHeadersCount() {
        return mHeadersView.size();
    }

    public int getFootersCount() {
        return mFootersView.size();
    }

    public int getRealItemCount() {
        return mAdapter.getItemCount();
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {
        if (isHeader(position)) {
            View view = mHeadersView.get(position);
            prepareHeaderFooter((HeaderFooterViewHolder) viewHolder, view);

        } else if (isFooter(position)) {
            View view = mFootersView.get(position - mAdapter.getItemCount() - mHeadersView.size());
            prepareHeaderFooter((HeaderFooterViewHolder) viewHolder, view);

        } else {
            mAdapter.onBindViewHolder(viewHolder, position - mHeadersView.size());
        }
    }

    /**
     * 头部或者底部预处理
     *
     * @param viewHolder
     * @param view
     */
    private void prepareHeaderFooter(HeaderFooterViewHolder viewHolder, View view) {
        if (mManagerType == TYPE_MANAGER_STAGGERED_GRID) {
            StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            layoutParams.setFullSpan(true);
            viewHolder.itemView.setLayoutParams(layoutParams);
        }

        if (view.getParent() != null) {
            ((ViewGroup) view.getParent()).removeView(view);
        }

        viewHolder.baseFrame.removeAllViews();
        viewHolder.baseFrame.addView(view);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
        ViewHolder viewHolder = null;
        if (type != TYPE_HEADER_VIEW && type != TYPE_FOOTER_VIEW) {
            viewHolder = mAdapter.onCreateViewHolder(viewGroup, type);
        } else {
            FrameLayout frameLayout = new FrameLayout(viewGroup.getContext());
            frameLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT));

            viewHolder = new HeaderFooterViewHolder(frameLayout);
        }

        return viewHolder;
    }

    /**
     * 头部或者底部的viewholder
     */
    public static class HeaderFooterViewHolder extends ViewHolder {
        private FrameLayout baseFrame;

        public HeaderFooterViewHolder(View itemView) {
            super(itemView);
            baseFrame = (FrameLayout) itemView;
        }
    }
}
